package com.ybbase.framework.common.util;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

/**
 * 日期处理工具类
 * @author shenaiguo
 * @date 2019.08.29 11:00
 * @since 4.0
 */
public class DateUtil {

    /**
     * TODO 后续删除
     */
    private final static SimpleDateFormat SDF_DATE_TIME = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private static DateTimeFormatter DTF_DATE_TIME = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    private static DateTimeFormatter DTF_DATE = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    private static final String PATTERN_DATE = "yyyy-MM-dd";
    private static final String PATTERN_TIME = "HH:mm:ss";
    private static final String PATTERN_DATETIME = "yyyy-MM-dd HH:mm:ss";
    private static final String PATTERN_FULL = "yyyy-MM-dd HH:mm:ss.SSS";


    /**
     * 获取YYYYMMDD格式
     * @return
     */
    public static String getDays() {
        return DTF_DATE.format(LocalDateTime.now());

    }

    /**
     * 获取YYYY-MM-DD HH:mm:ss格式
     * @return
     */
    public static String getTime() {
        return DTF_DATE_TIME.format(LocalDateTime.now());
    }

    /**
     * 获取YYYY-MM-DD 格式
     * @return
     */
    public static String getTime(Date date) {
        if (null == date) {
            return null;
        }
        return DTF_DATE.format(LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()));
    }

    /**
     * 获取YYYY-MM-DD HH:mm:ss格式
     * @return
     */
    public static String getDateTime(Date date) {
        if (null == date) {
            return null;
        }
        return DTF_DATE_TIME.format(LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()));
    }

    /**
     * @param startTime String 开始时间
     * @param endTime   String 结束时间
     * @param date      Date 对比时间
     * @return int
     * @author cg
     * @date 2019-08-28 18:01
     */
    public static int betweenDate(String startTime, String endTime, Date date) {
        int i = 0;
        try {
            if (StringUtils.isNotEmpty(startTime) && StringUtils.isNotEmpty(endTime)) {
                Date st = SDF_DATE_TIME.parse(startTime);
                Date et = SDF_DATE_TIME.parse(endTime);
                if (st.getTime() <= date.getTime() && et.getTime() > date.getTime()) {
                    i = 1;
                }
            } else if (StringUtils.isEmpty(startTime) && StringUtils.isNotEmpty(endTime)) {
                Date et = SDF_DATE_TIME.parse(endTime);
                if (et.getTime() > date.getTime()) {
                    i = 1;
                }
            } else if (StringUtils.isEmpty(startTime) && StringUtils.isNotEmpty(endTime)) {
                Date st = SDF_DATE_TIME.parse(startTime);
                if (st.getTime() < date.getTime()) {
                    i = 1;
                }
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return i;
    }

    /**
     * 账龄计算
     * @param createTime 创建时间
     * @return
     * @throws
     * @author wangjunjie
     * @date 2019/9/18 18:21
     * @since 4.0
     **/
    public static int accountAge(Date createTime) {
        Calendar from = Calendar.getInstance();
        from.setTime(createTime);
        Calendar to = Calendar.getInstance();
        to.setTime(new Date());
        int fromYear = from.get(Calendar.YEAR);
        int toYear = to.get(Calendar.YEAR);
        int year = toYear - fromYear;
        return year;
    }

    /**
     * 验证开始时间和结束时间
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return String
     * @author wangjunjie
     * @date 2019/9/10 15:35
     * @since 4.0
     **/
    public static boolean timeVerify(Date startTime, Date endTime) {
        return startTime.after(endTime);
    }

    /**
     * 获取时间戳
     * @param dateStr 时间
     * @author cg
     * @date 2019-10-14 16:21
     * @since 4.0
     */
    public static long getTimeStamp(String dateStr) {
        long timestamp = 0;
        try {
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            java.util.Date date = df.parse(dateStr);
            Calendar cal = Calendar.getInstance();
            cal.setTime(date);
            timestamp = cal.getTimeInMillis();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return timestamp;
    }

    /**
     * 获取距今天的任意天数的日期
     * @param days 时间天数 如果是负数则是当前时间多少天前，如果是正数则为当前多少天后
     * @return
     * @author cg
     * @date 2019-10-14 21:00
     * @since 4.0
     */
    public static String getLastAnyDay(String days) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar c = Calendar.getInstance();
        //过去七天
        c.setTime(new Date());
        c.add(Calendar.DATE, days.indexOf("-") != -1 ? -Integer.parseInt(days) : Integer.parseInt(days));
        Date d = c.getTime();
        return format.format(d);
    }

    /**
     * 验证开始时间和结束时间相差是否小于1分钟
     * @param date1 开始时间
     * @param str   结束时间 （当前时间）
     * @return String
     * @author shenaiguo
     * @date 2019-10-10 15:35
     * @since 4.0
     **/
    public static boolean isSameDate(Date date1, String str) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date2 = null;
        long min = 0;
        try {
            date2 = sdf.parse(str);
            long l = date2.getTime() - date1.getTime();
            long day = l / (24 * 60 * 60 * 1000);
            long hour = (l / (60 * 60 * 1000) - day * 24);
            min = ((l / (60 * 1000)) - day * 24 * 60 - hour * 60);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return min <= 1L;
    }

    /**
     * 截取时间格式的时分秒
     * @param days 时间
     * @return String
     * @author shenaiguo
     * @date 2019-10-30 15:35
     * @since 4.0
     **/
    public static String getloadTime(String days) {
        return days != null ? days.substring(days.indexOf(" ") + 1, days.length()).trim() : null;
    }

    /**
     * 时间格式化，只保留年月日
     *
     * @param calendar 时间
     * @return 保留年月日的时间
     * @author yanBin
     * @date 2019/11/1 16:57
     * @since 4.0
     */
    public static Calendar dateFormat(Calendar calendar) {
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar;
    }

    /**
     * 设置当年第一一天
     *
     * @param
     * @return java.util.Calendar
     * @author yanBin
     * @date 2019/11/7 21:04
     * @since 4.0
     */
    public static Calendar getYearsFirstDay() {
        //设置当年第一一天
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MONTH, 0);
        calendar.set(Calendar.DATE, 1);
        calendar = DateUtil.dateFormat(calendar);
        return calendar;
    }

    public static Calendar getLastYearFirstDay() {
        //设置当年第一一天
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.YEAR, -1);
        calendar.set(Calendar.MONTH, 0);
        calendar.set(Calendar.DATE, 1);
        calendar = DateUtil.dateFormat(calendar);
        return calendar;
    }

    public static Calendar getLastYearLastDay() {
        //设置当年第一一天
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, -1);
        calendar.set(Calendar.MONTH, 0);
        calendar.set(Calendar.DATE, 1);
        calendar = DateUtil.dateFormat(calendar);
        return calendar;
    }
    /**
     * 截取date 时间的月份
     *
     * @param date 时间
     * @return String
     * @author shenaiguo
     * @date 2019-10-30 15:35
     * @since 4.0
     **/
    public static int getMonth(Date date) {
        if (date == null){
            return 0;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.MONTH)+1;
    }

//    public static void main(String[] args) {
//        System.out.println(getMonth(new Date()));
//    }



    public static void main(String[] args) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(sdf.format(getStartTime()));
        System.out.println(sdf.format(getEndTime()));
    }

    /**
     * 获取系统当天开始时间
     * @return ResponseBean
     * @author junjie wang
     * @date 2019/11/5 10:57
     * @since 4.0
     */
    public static Date getStartTime() {
        Calendar todayStart = Calendar.getInstance();
        todayStart.set(Calendar.HOUR_OF_DAY, 0);
        todayStart.set(Calendar.MINUTE, 0);
        todayStart.set(Calendar.SECOND, 0);
        todayStart.set(Calendar.MILLISECOND, 0);
        return todayStart.getTime();
    }
    /**
     * 获取系统当天结束时间
     * @return ResponseBean
     * @author junjie wang
     * @date 2019/11/5 10:57
     * @since 4.0
     */
    public static Date getEndTime() {
        Calendar todayEnd = Calendar.getInstance();
        todayEnd.set(Calendar.HOUR_OF_DAY, 23);
        todayEnd.set(Calendar.MINUTE, 59);
        todayEnd.set(Calendar.SECOND, 59);
        todayEnd.set(Calendar.MILLISECOND, 999);
        return todayEnd.getTime();
    }

    public static final Date parse(String pattern, String source) {
        try {
            return new SimpleDateFormat(pattern, Locale.US).parse(source);
        } catch (ParseException e) {
            throw new RuntimeException("parse date error : ", e);
        }
    }


    public static final Date parseDateTime(String source) {
        try {
            return new SimpleDateFormat(PATTERN_DATETIME).parse(source);
        } catch (ParseException e) {
            throw new RuntimeException("parse date error : ", e);
        }
    }


    public static final Date parseDate(String source) {
        try {
            return new SimpleDateFormat(PATTERN_DATE).parse(source);
        } catch (ParseException e) {
            throw new RuntimeException("parse date error : ", e);
        }
    }


    public static final Date parseTime(String source) {
        try {
            return new SimpleDateFormat(PATTERN_TIME).parse(source);
        } catch (ParseException e) {
            throw new RuntimeException("parse date error : ", e);
        }
    }


    public static final Date parseFull(String source) {
        try {
            return new SimpleDateFormat(PATTERN_FULL).parse(source);
        } catch (ParseException e) {
            throw new RuntimeException("parse date error : ", e);
        }
    }

}
